package com.aracky.flowable.service.impl;

import com.aracky.common.exception.BaseException;
import com.aracky.common.util.ConvertUtil;
import com.aracky.common.vo.PageVO;
import com.aracky.flowable.mapper.FlowableMapper;
import com.aracky.flowable.model.dto.AcceptOrRejectDTO;
import com.aracky.flowable.model.dto.StartFlowableDTO;
import com.aracky.flowable.model.request.DoneRequest;
import com.aracky.flowable.model.request.TodoRequest;
import com.aracky.flowable.model.vo.DoneTaskVO;
import com.aracky.flowable.model.vo.TodoTaskVO;
import com.aracky.flowable.service.FlowTaskService;
import com.aracky.flowable.utils.PageUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author zengzhiping
 * @BelongsPackage com.aracky.flowable.service.impl
 * @CreateTime 2022-08-17
 * @Description
 */
@Service
@DS("flowable")
public class FlowTaskServiceImpl implements FlowTaskService {
    @Autowired
    private TaskService taskService;

    @Resource
    private FlowableMapper flowableMapper;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RuntimeService runtimeService;

    @Override
    public String startFlowable(StartFlowableDTO dto) {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
                dto.getProcessDefinitionKey(),
                dto.getBusinessKey(),
                dto.getMap()
        );
        return "启动流程成功，流程实例ID为：" + processInstance.getId();
    }

    @Override
    public void batchStartFlowable(List<StartFlowableDTO> dtoList) {
        for (StartFlowableDTO dto : dtoList) {
            runtimeService.startProcessInstanceByKey(
                    dto.getProcessDefinitionKey(),
                    dto.getBusinessKey(),
                    dto.getMap()
            );
        }
    }

    @Override
    public PageVO<TodoTaskVO> todoList(TodoRequest todoRequest) {
        //查询总条数
        long count = taskService.createTaskQuery().taskAssignee(todoRequest.getUserId()).count();

        //分页
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(todoRequest.getUserId())
                .orderByTaskCreateTime().desc()
                .listPage(todoRequest.getPage() - 1, todoRequest.getSize());

        //构造分页信息
        List<TodoTaskVO> todoTaskVOS = ConvertUtil.sourceToTargets(taskList, TodoTaskVO.class);

        //查询流程的变量信息
        todoTaskVOS.stream().forEach(todoTaskVO -> {
            String desc = (String)taskService.getVariable(todoTaskVO.getId(), "desc");
            todoTaskVO.setDesc(desc);
            //获取业务key
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(todoTaskVO.getProcessInstanceId())
                    .singleResult();
            String businessKey = processInstance.getBusinessKey();
            todoTaskVO.setBusinessKey(businessKey);
        });
        return PageUtil.buildPage(todoRequest.getPage(), todoRequest.getSize(), count, todoTaskVOS);
    }

    @Override
    public PageVO<DoneTaskVO> doneList(DoneRequest doneRequest) {
        IPage<DoneTaskVO> doneEntityIPage = flowableMapper.doneByUserId(doneRequest.toPage(), doneRequest.getUserId());
        return PageVO.convertPage(doneEntityIPage);
    }

    @Override
    public String acceptOrReject(AcceptOrRejectDTO dto) {
        Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();

        //判断当前流程是否被挂起
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
        if (processInstance == null || processInstance.isSuspended()) {
            throw new BaseException("当前流程实例已被挂起");
        }

        //领取任务
        taskService.claim(task.getId(), dto.getUserId());
        // 完成
        taskService.complete(task.getId(), dto.getMap());
        return "流程执行成功！";
    }

    @Override
    public List<Task> tasks(String group) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(group).list();
        return tasks;
    }

    @Override
    public List<HistoricActivityInstance> historicActivityInstances(String processInstanceId) {
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).finished().orderByHistoricActivityInstanceEndTime().asc().list();
        return historicActivityInstances;
    }

    @Override
    public String currentTask(String taskId, String targetTaskKey) {
        Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (currentTask == null) {
            return "节点不存在";
        }
        List<String> key = new ArrayList<>();
        key.add(currentTask.getTaskDefinitionKey());
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(currentTask.getProcessInstanceId())
                .moveActivityIdsToSingleActivityId(key, targetTaskKey)
                .changeState();
        return "驳回成功...";
    }


}
